import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.general.PieDataset;
import org.jfree.data.general.SeriesException;
import org.jfree.data.time.Month;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.RectangleInsets;

public class PlotGraph extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = -399582819997415162L;
	private static JPanel contentPane;
	final static JFrame f = new JFrame();
	public static JPanel graphPanel = new JPanel();  
	public static JTextField tfEndDate,tfStartDate;
	public static JButton btnEndDate, btnStartDate;
	private static JLabel lblEndDate,lblStartDate;
	private static JComboBox cbListReports;
	/**
	 * Launch the application.
	 */

	private void setDatePickersFalse()
	{
		btnEndDate.setVisible(false);
		tfEndDate.setVisible(false);
		lblEndDate.setVisible(false);		
		btnStartDate.setVisible(false);		
		tfStartDate.setVisible(false);		
		lblStartDate.setVisible(false);
	}

	private void setDatePickersTrue()
	{
		btnEndDate.setVisible(true);
		tfEndDate.setVisible(true);
		lblEndDate.setVisible(true);		
		btnStartDate.setVisible(true);		
		tfStartDate.setVisible(true);		
		lblStartDate.setVisible(true);	 
	}

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					PlotGraph frame = new PlotGraph();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public PlotGraph() {

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setTitle("Graph Reports");
		setBounds(100, 100, 700, 560);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);

		JLabel lblGraphType = new JLabel("Graph Type:");
		lblGraphType.setBounds(5, 8, 70, 20);
		contentPane.add(lblGraphType);

		cbListReports = new JComboBox(getGraphNames());
		cbListReports.setBounds(85,8,140,20);
		contentPane.add(cbListReports);

		cbListReports.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {

				JComboBox cbListReports = (JComboBox) event.getSource();
				String selected = (String) cbListReports.getSelectedItem();
				if(selected=="Income & Expenditure")
				{
					setDatePickersTrue();
				}
				else if(selected== "Expenditure by Category")
				{
					setDatePickersFalse(); 
				}
				else if(selected=="Choose Report")
				{
					setDatePickersFalse();
				}
			}
		});

		lblStartDate = new JLabel("Start Date: ");
		lblStartDate.setBounds(230,5,70,20);
		contentPane.add(lblStartDate);
		lblStartDate.setVisible(false);

		tfStartDate = new JTextField("-------------->", 10);
		tfStartDate.setBounds(300,5,75,20);
		contentPane.add(tfStartDate);
		tfStartDate.setEditable(false);
		tfStartDate.setVisible(false); 

		btnStartDate = new JButton();
		btnStartDate.setBounds(390,5,82,20);
		contentPane.add(btnStartDate);
		btnStartDate.setText("Set Date");
		btnStartDate.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e)
			{
				btnStartDate_actionPerformed(e);
			}
		});
		btnStartDate.setVisible(false);

		lblEndDate = new JLabel("End Date: ");
		lblEndDate.setBounds(230,35,70,20);
		contentPane.add(lblEndDate);
		lblEndDate.setVisible(false);

		tfEndDate = new JTextField("-------------->", 10);
		tfEndDate.setBounds(300,35,75,20);
		contentPane.add(tfEndDate);
		tfEndDate.setEditable(false);
		tfEndDate.setVisible(false);

		btnEndDate = new JButton();
		btnEndDate.setBounds(390,35,82,20);
		contentPane.add(btnEndDate);
		btnEndDate.setText("Set Date");
		btnEndDate.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e)
			{
				btnEndDate_actionPerformed(e);
			}
		});
		btnEndDate.setVisible(false);

		JButton btnGenGraph = new JButton("Generate Graph");
		btnGenGraph.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnGenerateGraph_actionPerformed(e);
			}
		});
		btnGenGraph.setBounds(20, 65, 150, 20);
		contentPane.add(btnGenGraph);



		JButton btnBack = new JButton("Back");
		btnBack.setBounds(200, 65, 150, 20);
		contentPane.add(btnBack);
		btnBack.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				dispose();
				MainMenu page=new MainMenu(); // Open the next page..
				page.setVisible(true); // Makes the next page visible
			}
		});
		contentPane.add(graphPanel);
		graphPanel.setBounds(5,90,675,425);
	}

	private void btnGenerateGraph_actionPerformed(ActionEvent e) //throws ParseException
	{
		String dateStart = tfStartDate.getText();
		String dateEnd = tfEndDate.getText();

		if(dateStart != "-------------->" || dateEnd != "-------------->")//if date is not set
		{
			String selected = (String) cbListReports.getSelectedItem();
			if(selected=="Income & Expenditure")
			{
				graphPanel.removeAll();
				graphPanel.updateUI(); 
				graphPanel.add(createDemoPanel());
				graphPanel.validate();
			}
			else if(selected== "Expenditure by Category")
			{
				graphPanel.removeAll();
				graphPanel.updateUI(); 
				graphPanel.add(createTimeSeriesDemoPanel());
				graphPanel.validate();
				
			}
			else if(selected=="Choose Report")
			{
				JOptionPane.showMessageDialog(PlotGraph.contentPane, "Please select a graph type to generate!");
			}
		}
	}

	public String[] getGraphNames()
	{//Function for generating each combo box option for the reports
		String[] listReportItems = {"Choose Report", "Income & Expenditure", "Expenditure by Category"};
		return listReportItems;
	}

	private void btnEndDate_actionPerformed(ActionEvent e)
	{	//Calls date picker for end date for the reports
		tfEndDate.setText(new DatePicker(f).setPickedDate());
	}

	private void btnStartDate_actionPerformed(ActionEvent e)
	{	//Calls date picker for the start date for the reports
		tfStartDate.setText(new DatePicker(f).setPickedDate());//Calls date picker
	}

	@SuppressWarnings("unchecked")
	private static PieDataset createDataset() {
		DefaultPieDataset dataset = new DefaultPieDataset();

		FileInputStream fis = null;
		ObjectInputStream in = null;
		File expFile = new File("ExpenditureList.ser");
		if(expFile.exists())
		{
			try {
				fis = new FileInputStream(expFile);
				in = new ObjectInputStream(fis);
				Expenditure.expenditureList = (ArrayList<Expenditure>) in.readObject();//Reads in the income list from the file
				in.close();
			} catch (Exception ex) {
				System.out.println("Exception during deserialization: " +
						ex); 
				ex.printStackTrace();
			}
		}

		for(int i = 0; i < Expenditure.expenditureList.size();i++)
		{
			Expenditure getExpense = Expenditure.expenditureList.get(i);

			for(int j = 0; j < Expenditure.expenditureList.size();j++)
			{
				try{
					if(getExpense.getCategory().toString().equals(dataset.getKey(j).toString()))
					{
						Double newValue = dataset.getValue(j).doubleValue() + getExpense.getAmount();
						dataset.insertValue(j, getExpense.getCategory(), newValue);
						break;
					}
					else
					{
						dataset.setValue(getExpense.getCategory(), getExpense.getAmount());
						break;
					}
				}catch(IndexOutOfBoundsException ex){
					dataset.setValue(getExpense.getCategory(), getExpense.getAmount());
				}
			}
		}
		return dataset;
	}

	private static JFreeChart createChart(PieDataset dataset) {

		JFreeChart chart = ChartFactory.createPieChart(
				"Pie Chart Demo 1",  // chart title
				dataset,             // data
				true,                // include legend
				true,
				false
				);
		chart.setBackgroundPaint(graphPanel.getBackground());
		PiePlot plot = (PiePlot) chart.getPlot();
		plot.setSectionOutlinesVisible(false);
		plot.setNoDataMessage("No data available");
		return chart;
	}

	public static JPanel createDemoPanel() {
		JFreeChart chart = createChart(createDataset());
		ChartPanel panel = new ChartPanel(chart);
		panel.setMouseWheelEnabled(true);
		return panel;
	}
	
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
	
	private static JFreeChart createChart(XYDataset dataset) {

		JFreeChart chart = ChartFactory.createTimeSeriesChart(
				"Income vs Expenditure",  // title
				"Date",             // x-axis label
				"Amount",   // y-axis label
				dataset,            // data
				true,               // create legend?
				true,               // generate tooltips?
				false               // generate URLs?
				);

		chart.setBackgroundPaint(graphPanel.getBackground());

		XYPlot plot = (XYPlot) chart.getPlot();
		plot.setBackgroundPaint(Color.lightGray);
		plot.setDomainGridlinePaint(Color.white);
		plot.setRangeGridlinePaint(Color.white);
		plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
		plot.setDomainCrosshairVisible(true);
		plot.setRangeCrosshairVisible(true);
		XYItemRenderer r = plot.getRenderer();
		if (r instanceof XYLineAndShapeRenderer) {
			XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) r;
			renderer.setBaseShapesVisible(true);
			renderer.setBaseShapesFilled(true);
			renderer.setDrawSeriesLineAsPath(true);
		}

		DateAxis axis = (DateAxis) plot.getDomainAxis();
		axis.setDateFormatOverride(new SimpleDateFormat("MMM-yyyy"));
		//axis.setDateFormatOverride(new SimpleDateFormat("dd-MM-yyyy"));

		return chart;

	}

	/**
	 * Creates a dataset, consisting of two series of monthly data.
	 *
	 * @return The dataset.
	 */
	@SuppressWarnings("unchecked")
	private static XYDataset createTimeSeriesDataset(){
		TimeSeries s1 = new TimeSeries("Income");
		TimeSeries s2 = new TimeSeries("Expenditure");
		/*		String dateStart = PlotGraph.tfStartDate.getText();
		String dateEnd = PlotGraph.tfEndDate.getText();*/
		String dateStart = "01-01-2000";
		String dateEnd = "01-01-2015";

		File filename = new File("IncomeList.ser");
		FileInputStream fis = null;
		ObjectInputStream in = null;
		if(filename.exists())
		{
			try {
				fis = new FileInputStream(filename);
				in = new ObjectInputStream(fis);
				Income.incomeList = (ArrayList<Income>) in.readObject();//Reads in the income list from the file
				in.close();
			} catch (Exception ex) {
				System.out.println("Exception during deserialization: " +
						ex); 
				ex.printStackTrace();
			}
		}
		
		File expFile = new File("ExpenditureList.ser");
/*		FileInputStream fis = null;
		ObjectInputStream in = null;*/
		if(expFile.exists())
		{
			try {
				fis = new FileInputStream(expFile);
				in = new ObjectInputStream(fis);
				Expenditure.expenditureList = (ArrayList<Expenditure>) in.readObject();//Reads in the income list from the file
				in.close();
			} catch (Exception ex) {
				System.out.println("Exception during deserialization: " +
						ex); 
				ex.printStackTrace();
			}
		}
		
		// dataset.setValue(incomeAdd.getDescription(),incomeAdd.getAmount());

		Calendar calStartDate = new GregorianCalendar();
		Calendar calEndDate = new GregorianCalendar();



		java.util.Date startDate;
		try {
			startDate = new SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH).parse(dateStart);

			calStartDate.setTime(startDate);
			java.util.Date endDate = new SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH).parse(dateEnd);
			calEndDate.setTime(endDate);

			for(int i = 0; i<Income.incomeList.size();i++)//loops through each patient
			{
				Income incomeGraph = Income.incomeList.get(i);

				String strDateCompare = incomeGraph.getDate().toString();//Gets date from invoice
				Calendar calDateCompare = new GregorianCalendar();
				java.util.Date dtDateCompare = new SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH).parse(strDateCompare);//converts string to date
				calDateCompare.setTime(dtDateCompare);

				if(calDateCompare.after(calStartDate) && calDateCompare.before(calEndDate))
				{


					try
					{
						s1.add(new Month(calDateCompare.get(Calendar.MONTH), calDateCompare.get(Calendar.YEAR)), incomeGraph.getAmount());
					}
					catch(SeriesException e)
					{							
						Double newAmount =(Double) s1.getDataItem(new Month(calDateCompare.get(Calendar.MONTH), calDateCompare.get(Calendar.YEAR))).getValue();
						s1.addOrUpdate(new Month(calDateCompare.get(Calendar.MONTH), calDateCompare.get(Calendar.YEAR)), incomeGraph.getAmount() + newAmount);
					}
					//System.out.println(s1.getDataItem(i).getPeriod().toString());
				}

			}
			
			for(int i = 0; i<Expenditure.expenditureList.size();i++)//loops through each patient
			{
				Expenditure expenseGraph = Expenditure.expenditureList.get(i);

				String strDateCompare = expenseGraph.getDate().toString();//Gets date from invoice
				Calendar calDateCompare = new GregorianCalendar();
				java.util.Date dtDateCompare = new SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH).parse(strDateCompare);//converts string to date
				calDateCompare.setTime(dtDateCompare);

				if(calDateCompare.after(calStartDate) && calDateCompare.before(calEndDate))
				{


					try
					{
						s2.add(new Month(calDateCompare.get(Calendar.MONTH), calDateCompare.get(Calendar.YEAR)), expenseGraph.getAmount());
					}
					catch(SeriesException e)
					{							
						Double newAmount =(Double) s2.getDataItem(new Month(calDateCompare.get(Calendar.MONTH), calDateCompare.get(Calendar.YEAR))).getValue();
						s2.addOrUpdate(new Month(calDateCompare.get(Calendar.MONTH), calDateCompare.get(Calendar.YEAR)), expenseGraph.getAmount() + newAmount);
					}
					//System.out.println(s1.getDataItem(i).getPeriod().toString());
				}

			}

		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		TimeSeriesCollection dataset = new TimeSeriesCollection();
		dataset.addSeries(s1);
		dataset.addSeries(s2);

		return dataset;

	}

	/**
	 * Creates a panel for the demo (used by SuperDemo.java).
	 *
	 * @return A panel.
	 */
	public static JPanel createTimeSeriesDemoPanel(){
		JFreeChart chart = createChart(createTimeSeriesDataset());
		ChartPanel panel = new ChartPanel(chart);
		panel.setFillZoomRectangle(true);
		panel.setMouseWheelEnabled(true);
		return panel;
	}
}